/**
 * 
 */
package synchro;

import java.util.Vector;

/**
 * Creation date: Nov 12, 2007
 * Use case: 
 *
 * @author: cristian.rasch
 */
public abstract class Dispatcher implements Runnable {

    private Vector tasks = new Vector();

    private boolean stop;

    protected Dispatcher() {
        new Thread(this).start();
    }

    protected void execute(Runnable task) {
        if (!stop) {
            synchronized (tasks) {
                tasks.addElement(task);
                tasks.notify();
            }
        }
    }

    public void run() {
        while (!stop || !tasks.isEmpty()) {
            Runnable task = null;

            synchronized (tasks) {
                while (!stop && tasks.isEmpty()) {
                    try {
                        tasks.wait();
                    }
                    catch (InterruptedException e) {}
                }

                if (!tasks.isEmpty()) {
                    task = (Runnable) tasks.elementAt(0);
                    tasks.removeElementAt(0);
                }
            }

            try {
                task.run();
            } catch(Exception e) {
                handleException(e);
            }
        }
    }

    protected void stop() {
        synchronized (tasks) {
            stop = true;
            tasks.notify();
        }
    }
    
    protected abstract void handleException(Exception exception);
}
